package com.example.myproject.jackson;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.core.io.NumberInput;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;

import java.io.IOException;

/**
 * Created by xi on 2018/9/21.
 * BeanDeserializer
 * 参考NumberDeserializers 这个实现类
 */
public class JacksonIntegerDeSerializer extends NewPrimitiveOrWrapperDeserializer<Integer> {
        private static final long serialVersionUID = 1L;
        public JacksonIntegerDeSerializer(){this(Integer.TYPE, null);};
        public JacksonIntegerDeSerializer(Class<Integer> cls, Integer nvl) {
            super(cls, nvl, null);
        }

        // since 2.6, slightly faster lookups for this very common type
        @Override
        public boolean isCachable() { return true; }

        @Override
        public Integer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            if (p.hasToken(JsonToken.VALUE_NUMBER_INT)) {
                return p.getIntValue();
            }
            return _parseInteger(p, ctxt);
        }

        // Since we can never have type info ("natural type"; String, Boolean, Integer, Double):
        // (is it an error to even call this version?)
        @Override
        public Integer deserializeWithType(JsonParser p, DeserializationContext ctxt,
                                           TypeDeserializer typeDeserializer) throws IOException
        {
            //如果传递的数字
            if (p.hasToken(JsonToken.VALUE_NUMBER_INT)) {
                return p.getIntValue();
            }
            //传递的字符
            return _parseInteger(p, ctxt);
        }

        protected final Integer _parseInteger(JsonParser p, DeserializationContext ctxt) throws IOException
        {
            switch (p.getCurrentTokenId()) {
                // NOTE: caller assumed to usually check VALUE_NUMBER_INT in fast path
                case JsonTokenId.ID_NUMBER_INT:
                    return Integer.valueOf(p.getIntValue());
                case JsonTokenId.ID_NUMBER_FLOAT: // coercing may work too
                    if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_FLOAT_AS_INT)) {
                        _failDoubleToIntCoercion(p, ctxt, "Integer");
                    }
                    return Integer.valueOf(p.getValueAsInt());
                case JsonTokenId.ID_STRING: // let's do implicit re-parse
                    String text = p.getText().trim();
                    int len = text.length();
                    //做默认的逻辑
                    if (len == 0) {
                        return (Integer) UpdateSpecialConstant.INT_SPECAIL_VALUE;
                       // return (Integer) _coerceEmptyString(ctxt, _primitive);
                    }

                    if (_hasTextualNull(text)) {
                        return (Integer) _coerceTextualNull(ctxt, _primitive);
                    }
                    _verifyStringForScalarCoercion(ctxt, text);
                    try {
                        if (len > 9) {
                            long l = Long.parseLong(text);
                            if (_intOverflow(l)) {
                                return (Integer) ctxt.handleWeirdStringValue(_valueClass, text, String.format(
                                        "Overflow: numeric value (%s) out of range of Integer (%d - %d)",
                                        text, Integer.MIN_VALUE, Integer.MAX_VALUE));
                            }
                            return Integer.valueOf((int) l);
                        }
                        return Integer.valueOf(NumberInput.parseInt(text));
                    } catch (IllegalArgumentException iae) {
                        return (Integer) ctxt.handleWeirdStringValue(_valueClass, text,
                                "not a valid Integer value");
                    }
                case JsonTokenId.ID_NULL:
                    return (Integer) _coerceNullToken(ctxt, _primitive);
                case JsonTokenId.ID_START_ARRAY://有可能数字传递[]
                    return _deserializeFromArray(p, ctxt);
            }
            // Otherwise, no can do:
            return (Integer) ctxt.handleUnexpectedToken(_valueClass, p);
        }
}
